1. Technical Field
The present application relates to processor communications and in particular but not exclusively for processor communication for controlling shared memory data flow. One embodiment is for controlling multiprocessor data transfers accessing a shared memory on a single integrated circuit package, but can be used in any shared memory controller.
2. Discussion of the Related Art
Microprocessor-based systems are increasingly containing multiple central processor units (CPU) or cores which are required to communicate with each other. A method for implementing this communication between CPU cores is to use an area of shared memory.
However using shared memory requires the control of the flow of data through the shared memory area. For example the shared memory area is required to be controlled such that the receiving processor does not attempt to read data before the sender has placed it in the memory, a read after write (RAW) hazard, where the receiving processor accesses the old data. Furthermore the shared memory should be controlled such that the sending processor does not attempt to overwrite data in the shared memory before the receiver has read the data on the memory, a write after read (WAR) hazard where the receiver cannot access the old data.
These hazards have been researched and proposed solutions have involved implementing flow control in shared memory as a circular buffer where the sender send a write pointer (WP), indicating the next memory location to be sent data by the sender, to the receiver and the receiver sends a read pointer (RP), indicating the next memory location to the read from by receiver, to the sender.
In such examples the sender places data in the buffer, updates its local write pointer, and sends the new pointer value to the receiver.
The receiver receives the updated write pointer, compares it to its read pointer and the comparison enables the receiver to determine whether it can read data from the current read pointer address (in other words the receiver when detecting the difference between the read pointer and write pointer is greater than a threshold enables a read operation to occur).
The receiver when a read operation on the shared memory is performed can then send an updated read pointer back to the sender.
The sender, on receiving the updated read pointer, has the information that the receiver has read the data from the buffer, and thus can ‘clear’ the memory space, enabling the sender to write data again providing the sender write operation does not result in the write pointer catching up with or passing the read pointer.
However such communication of pointers between the processors may require pointers which are large enough to address the whole of the buffer. For example a buffer with 256 locations requires a minimum of eight bits per pointer. Furthermore the flow control can implement pointers as relative addresses (relative to the base of the buffer), or absolute addresses. Thus the read and write pointers can require typically 32 bit addressing capability (or even larger numbers of bits per pointer).
Furthermore such communication is problematic where the sender and receiver are on separate chips (or on the same chip) separated by significant routing distance. In such examples the overhead of communicating multiple wires between the sender and receiver could be unacceptably high.
Although there has been suggestion that further shared memory locations can be used to store the read and write pointer values, and thus not require the transfer of write and read pointers between the central processing units, the use of additional shared memory space places different communication loads on both the sender and receiver to poll the pointer locations for updated pointer values.
Furthermore where the sender and receiver are in separate clock domains the communication of read and write pointers require additional hardware to ensure the pointers are communicated safely without corruption due to clock domain boundary errors.
Further flow control designs determine a common transfer size between sender and receiver, enable the sender to maintain local read and write pointers, and enable the receiver to maintain a local read pointer. Such examples further are configured to allow the sender to contain a memory mapped register which drives a request signal to the receiver. Furthermore in such examples allow the receiver to contain a further memory mapped register which drives and an acknowledgement signal to the sender. In such examples the sender can place data into the buffer, update the sender write pointer, then compare the read and write pointers so that where the sender determines that the amount of data in the buffer is more than the agreed transfer size the sender sets a request signal by writing to the memory mapped register.
The receiver sees the request signal asserted and reads the agreed amount of data from the shared memory buffer. Once the receiver has read the data the receiver uses the receiver memory mapped register to invert the acknowledged signal. The sender then detects the edge of the acknowledged signal and updates the sender read pointer to take account of the data read from the shared memory buffer. Then based on the current fill level of the shared memory buffer the sender can choose to clear or assert the request signal.
These examples of flow control allow flow control to be maintained because the receiver will not attempt to read data from the buffer unless the request is asserted. Also the sender will not write data into the buffer if the write pointer passes the read pointer as the sequence of edges on the acknowledge signal ensure that the sender's copy of the read pointer is kept up to date.
In such examples only two wires between the sender and receiver, a request write wire and an acknowledge wire are required. However the request and acknowledge signals require very fast propagation between the sender and receiver. Where propagation is slow then the receiver can poll the request signal before the previous acknowledgement edge has propagated through to the de-assertion of the request resulting in a single request being serviced twice by the sender. This can for example generate memory buffer underflow.